using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ViScript.Core;
using ViScript.Core.Blocks;
using ViScript.Core.ParsedSentence;
using ViScript.Core.Utils;

namespace ViScript.Example
{
    public class ParsedSentenceVisualizer : IParsedSentenceVisitor
    {
        private readonly TreeNodeCollection nodes;
        private readonly IEscapeStrategy escapeStrategy;

        public ParsedSentenceVisualizer(TreeNodeCollection nodes, IEscapeStrategy escapeStrategy)
        {
            this.nodes = nodes;
            this.escapeStrategy = escapeStrategy;
        }

        public void VisitAmbiguous(AmbiguousParsedSentence ambiguousParsedSentence)
        {
            string text = GetSentenceContent(ambiguousParsedSentence.Sentence);
            TreeNode treeNode = new TreeNode(text);
            treeNode.BackColor = Color.Orange;
            nodes.Add(treeNode);
        }

        public void VisitNormal(NormalParsedSentence normalParsedSentence)
        {
            string text = GetSentenceContent(normalParsedSentence.Sentence);
            TreeNode treeNode = new TreeNode(text);
            NormalParsedSentenceVisualizer visualizer = new NormalParsedSentenceVisualizer(treeNode.Nodes);
            normalParsedSentence.SentenceRule.Accept(visualizer);
            normalParsedSentence.Arguments.Accept(visualizer);
            nodes.Add(treeNode);
        }

        public void VisitUnrecognized(UnrecognizedParsedSentence unrecognizedParsedSentence)
        {
            string text = GetSentenceContent(unrecognizedParsedSentence.Sentence);
            TreeNode treeNode = new TreeNode(text);
            treeNode.BackColor = Color.Pink;
            nodes.Add(treeNode);
        }

        private string GetSentenceContent(ISentence sentence)
        {
            string text = sentence.ToString();
            return Unescape(text).Trim();
        }

        private string Unescape(IEnumerable<char> escapedText)
        {
            RootBlock rootBlock = new RootBlock(escapeStrategy);
            foreach (char c in escapedText)
            {
                rootBlock.Append(c);
            }
            return rootBlock.Unescape();
        }
    }
}